// 包含必要的头文件
#include "RingQueue.hpp" // 环形队列头文件
#include "Thread.hpp"    // 线程类头文件
#include "Task.hpp"      // 任务类头文件
#include <string>
#include <vector>
#include <unistd.h>       // 提供sleep函数
#include <ctime>          // 提供时间相关函数

// 使用ThreadModule命名空间
using namespace ThreadModule;
// 定义环形队列类型别名：存储Task类型的环形队列
using ringqueue_t = RingQueue<Task>;

// 消费者函数：从环形队列中取出任务并执行
// 参数rq：环形队列引用
// 参数name：消费者名称
void Consumer(ringqueue_t &rq, std::string name)
{
    while (true)
    {
        // 每2秒执行一次消费操作
        sleep(2);
        
        // 1. 从队列中取出一个任务
        Task task;
        rq.Pop(&task);
        
        // 2. 执行任务（计算两数之和）
        task.Excute();
        
        // 3. 输出任务执行结果
        std::cout << "Consumer handler data: " << task.ResultToString() << "[" << name << "]" << std::endl;
    }
}

// 生产者函数：生成随机任务并加入环形队列
// 参数rq：环形队列引用
// 参数name：生产者名称
void Productor(ringqueue_t &rq, std::string name)
{
    // 设置随机数种子，结合时间和线程ID确保每个线程的随机序列不同
    srand(time(nullptr) ^ pthread_self());
    
    // 计数器（虽然定义了但没有实际使用，循环会一直执行）
    int cnt = 10;
    
    while (true)
    {
        // 生成随机任务：两个0-99之间的随机数
        Task task(rand() % 100, rand() % 100);
        
        // 将任务加入环形队列
        rq.Enqueue(task);
        
        // 输出任务信息
        std::cout << "Productor : " << task.DebugToString() << "[" << name << "]" << std::endl;
        
        // 计数器递减（无实际作用）
        cnt--;
    }
}

// 通用线程初始化函数：创建指定数量的线程并添加到线程容器中
// 参数threads：线程容器指针
// 参数num：要创建的线程数量
// 参数rq：环形队列引用
// 参数func：线程要执行的函数
// 参数who：线程类型标识（如"consumer"或"productor"）
void InitComm(std::vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq, func_t<ringqueue_t> func, const std::string &who)
{
    for (int i = 0; i < num; i++)
    {
        // 生成线程名称，格式为"thread-序号-类型"
        std::string name = "thread-" + std::to_string(i + 1) + "-" + who;
        
        // 创建线程对象并添加到容器中
        threads->emplace_back(func, rq, name);
        
        // 注意：这里注释了立即启动线程的代码，实际启动在线程全部创建完成后统一进行
    }
}

// 消费者线程初始化函数：创建指定数量的消费者线程
// 参数threads：线程容器指针
// 参数num：要创建的消费者线程数量
// 参数rq：环形队列引用
void InitConsumer(std::vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
    // 调用通用初始化函数，指定线程函数为Consumer
    InitComm(threads, num, rq, Consumer, "consumer");
}

// 生产者线程初始化函数：创建指定数量的生产者线程
// 参数threads：线程容器指针
// 参数num：要创建的生产者线程数量
// 参数rq：环形队列引用
void InitProductor(std::vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
    // 调用通用初始化函数，指定线程函数为Productor
    InitComm(threads, num, rq, Productor, "productor");
}

// 等待所有线程结束
// 参数threads：线程容器引用
void WaitAllThread(std::vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        // 调用每个线程的Join方法，等待线程结束
        thread.Join();
    }
}
    
// 启动所有线程
// 参数threads：线程容器引用
void StartAll(std::vector<Thread<ringqueue_t>> &threads)
{
    for(auto &thread : threads)
    {
        // 输出线程启动信息
        std::cout << "start: " << thread.name() << std::endl;
        
        // 启动线程
        thread.Start();
    }
}

// 主函数：程序入口点
int main()
{
    // 创建一个容量为10的环形队列
    ringqueue_t *rq = new ringqueue_t(10);
    
    // 创建线程容器，用于存储所有创建的线程
    std::vector<Thread<ringqueue_t>> threads;
    
    // 初始化生产者线程：创建1个生产者线程
    InitProductor(&threads, 1, *rq);
    
    // 初始化消费者线程：创建1个消费者线程
    InitConsumer(&threads, 1, *rq);
    
    // 启动所有线程
    StartAll(threads);
    
    // 等待所有线程结束（注意：在这个程序中，线程会一直运行，所以这里实际上不会返回）
    WaitAllThread(threads);
    
    // 注意：由于没有释放动态分配的环形队列rq，这里存在内存泄漏
    
    return 0;
}